/*
  Copyright (C) 2011, Kyungjoo Kim
  
  This file is part of UHM (Unassembled HyperMatrix) sparse direct solver.
  
  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  Also add information on how to contact you by electronic and paper mail.
  
  
  Kyungjoo Kim
  iamkyungjoo@gmail.com
*/
#ifndef UHM_OPERATION_ELEMENT_HXX
#define UHM_OPERATION_ELEMENT_HXX


namespace uhm {
  // ---------------------------------------------------
  extern bool op_create_matrix_buffer_without_schur  (Element e);
  extern bool op_create_matrix_buffer_with_schur     (Element e);

  extern bool op_restore_connectivity                (Element e);
  extern bool op_numbering                           (Element e);
  extern bool op_update_connectivity                 (Element e);
  extern bool op_arrange_nodes                       (Element e);
  extern bool op_update_generation                   (Element e);
  // ---------------------------------------------------
  extern bool op_merge_full_with_free                (Element e);
  extern bool op_merge_full_without_free             (Element e);
  extern bool op_merge_full_with_ooc                 (Element e);

  extern bool op_merge_rhs_x                         (Element e);
  extern bool op_merge_rhs_r                         (Element e);

  extern bool op_branch_rhs_x                        (Element e);
  extern bool op_branch_rhs_r                        (Element e);
  // ---------------------------------------------------
  extern bool op_chol_without_merge                  (Element e);
  extern bool op_chol_with_merge_and_free            (Element e);
  extern bool op_chol_with_merge_and_no_free         (Element e);

  extern bool op_solve_chol_1_x_without_merge        (Element e);
  extern bool op_solve_chol_1_x_with_merge           (Element e);
  extern bool op_solve_chol_2_x_without_branch       (Element e);
  extern bool op_solve_chol_2_x_with_branch          (Element e);

  extern bool op_solve_chol_1_r_without_merge        (Element e);
  extern bool op_solve_chol_1_r_with_merge           (Element e);
  extern bool op_solve_chol_2_r_without_branch       (Element e);
  extern bool op_solve_chol_2_r_with_branch          (Element e);

  extern bool op_check_chol_1                        (Element e);
  extern bool op_check_chol_2                        (Element e);
  // ---------------------------------------------------
  extern bool op_chol_incpiv_without_merge           (Element e);
  extern bool op_chol_incpiv_with_merge_and_free     (Element e);
  extern bool op_chol_incpiv_with_merge_and_no_free  (Element e);
  extern bool op_chol_incpiv_with_merge_and_ooc      (Element e);
  // ---------------------------------------------------
  extern bool op_chol_piv_without_merge              (Element e);
  extern bool op_chol_piv_with_merge_and_free        (Element e);
  extern bool op_chol_piv_with_merge_and_no_free     (Element e);
  extern bool op_chol_piv_with_merge_and_ooc         (Element e);
  // ---------------------------------------------------
  extern bool op_solve_chol_piv_1_x_without_merge    (Element e);
  extern bool op_solve_chol_piv_1_x_with_merge       (Element e);
  extern bool op_solve_chol_piv_2_x_without_branch   (Element e);
  extern bool op_solve_chol_piv_2_x_with_branch      (Element e);

  extern bool op_solve_chol_piv_1_r_without_merge    (Element e);
  extern bool op_solve_chol_piv_1_r_with_merge       (Element e);
  extern bool op_solve_chol_piv_2_r_without_branch   (Element e);
  extern bool op_solve_chol_piv_2_r_with_branch      (Element e);
  // ---------------------------------------------------
  extern bool op_check_chol_piv_1                    (Element e);
  extern bool op_check_chol_piv_2                    (Element e);
  // ---------------------------------------------------
  extern bool op_ldl_nopiv_without_merge             (Element e);
  extern bool op_ldl_nopiv_with_merge_and_free       (Element e);
  extern bool op_ldl_nopiv_with_merge_and_no_free    (Element e);
  extern bool op_ldl_nopiv_with_merge_and_ooc        (Element e);
  // ---------------------------------------------------
  extern bool op_solve_ldl_nopiv_1_x_without_merge   (Element e);
  extern bool op_solve_ldl_nopiv_1_x_with_merge      (Element e);
  extern bool op_solve_ldl_nopiv_2_x_without_branch  (Element e);
  extern bool op_solve_ldl_nopiv_2_x_with_branch     (Element e);

  extern bool op_solve_ldl_nopiv_1_r_without_merge   (Element e);
  extern bool op_solve_ldl_nopiv_1_r_with_merge      (Element e);
  extern bool op_solve_ldl_nopiv_2_r_without_branch  (Element e);
  extern bool op_solve_ldl_nopiv_2_r_with_branch     (Element e);
  // ---------------------------------------------------
  extern bool op_check_ldl_nopiv_1                   (Element e);
  extern bool op_check_ldl_nopiv_2                   (Element e);
  // ---------------------------------------------------
  extern bool op_ldl_incpiv_without_merge            (Element e);
  extern bool op_ldl_incpiv_with_merge_and_free      (Element e);
  extern bool op_ldl_incpiv_with_merge_and_no_free   (Element e);
  extern bool op_ldl_incpiv_with_merge_and_ooc       (Element e);
  // ---------------------------------------------------
  extern bool op_ldl_piv_without_merge               (Element e);
  extern bool op_ldl_piv_with_merge_and_free         (Element e);
  extern bool op_ldl_piv_with_merge_and_no_free      (Element e);
  extern bool op_ldl_piv_with_merge_and_ooc          (Element e);
  // ---------------------------------------------------
  extern bool op_solve_ldl_piv_1_x_without_merge     (Element e);
  extern bool op_solve_ldl_piv_1_x_with_merge        (Element e);
  extern bool op_solve_ldl_piv_2_x_without_branch    (Element e);
  extern bool op_solve_ldl_piv_2_x_with_branch       (Element e);

  extern bool op_solve_ldl_piv_1_r_without_merge     (Element e);
  extern bool op_solve_ldl_piv_1_r_with_merge        (Element e);
  extern bool op_solve_ldl_piv_2_r_without_branch    (Element e);
  extern bool op_solve_ldl_piv_2_r_with_branch       (Element e);
  // ---------------------------------------------------
  extern bool op_check_ldl_piv_1                     (Element e);
  extern bool op_check_ldl_piv_2                     (Element e);
  // ---------------------------------------------------
  extern bool op_lu_nopiv_without_merge              (Element e);
  extern bool op_lu_nopiv_with_merge_and_free        (Element e);
  extern bool op_lu_nopiv_with_merge_and_no_free     (Element e);

  extern bool op_solve_lu_nopiv_1_x_without_merge    (Element e);
  extern bool op_solve_lu_nopiv_1_x_with_merge       (Element e);
  extern bool op_solve_lu_nopiv_2_x_without_branch   (Element e);
  extern bool op_solve_lu_nopiv_2_x_with_branch      (Element e);

  extern bool op_solve_lu_nopiv_1_r_without_merge    (Element e);
  extern bool op_solve_lu_nopiv_1_r_with_merge       (Element e);
  extern bool op_solve_lu_nopiv_2_r_without_branch   (Element e);
  extern bool op_solve_lu_nopiv_2_r_with_branch      (Element e);

  extern bool op_check_lu_nopiv_1                    (Element e);
  extern bool op_check_lu_nopiv_2                    (Element e);
  // ---------------------------------------------------
  extern bool op_lu_incpiv_without_merge             (Element e);
  extern bool op_lu_incpiv_with_merge_and_free       (Element e);
  extern bool op_lu_incpiv_with_merge_and_no_free    (Element e);
  // ---------------------------------------------------
  extern bool op_lu_piv_without_merge                (Element e);
  extern bool op_lu_piv_with_merge_and_free          (Element e);
  extern bool op_lu_piv_with_merge_and_no_free       (Element e);


  extern bool op_solve_lu_piv_1_x_without_merge      (Element e);
  extern bool op_solve_lu_piv_1_x_with_merge         (Element e);
  extern bool op_solve_lu_piv_2_x_without_branch     (Element e);
  extern bool op_solve_lu_piv_2_x_with_branch        (Element e);

  extern bool op_solve_lu_piv_1_r_without_merge      (Element e);
  extern bool op_solve_lu_piv_1_r_with_merge         (Element e);
  extern bool op_solve_lu_piv_2_r_without_branch     (Element e);
  extern bool op_solve_lu_piv_2_r_with_branch        (Element e);

  extern bool op_check_lu_piv_1                      (Element e);
  extern bool op_check_lu_piv_2                      (Element e);
  // ---------------------------------------------------

  extern bool op_qr_without_merge                    (Element e);
  extern bool op_qr_with_merge_and_free              (Element e);
  extern bool op_qr_with_merge_and_no_free           (Element e);
  // ---------------------------------------------------
  extern bool op_solve_qr_1_x_without_merge          (Element e);
  extern bool op_solve_qr_1_x_with_merge             (Element e);
  extern bool op_solve_qr_2_x_without_branch         (Element e);
  extern bool op_solve_qr_2_x_with_branch            (Element e);

  extern bool op_solve_qr_1_r_without_merge          (Element e);
  extern bool op_solve_qr_1_r_with_merge             (Element e);
  extern bool op_solve_qr_2_r_without_branch         (Element e);
  extern bool op_solve_qr_2_r_with_branch            (Element e);

  extern bool op_check_qr_1                          (Element e);
  extern bool op_check_qr_2                          (Element e);
  // ---------------------------------------------------

  // ---------------------------------------------------

  extern bool op_chol_with_merge_and_ooc             (Element e);
  extern bool op_lu_nopiv_with_merge_and_ooc         (Element e);
  extern bool op_lu_piv_with_merge_and_ooc           (Element e);
  extern bool op_lu_incpiv_with_merge_and_ooc        (Element e);
  extern bool op_qr_with_merge_and_ooc               (Element e);

  extern bool op_solve_lu_piv_1_x_without_merge_ooc  (Element e);
  extern bool op_solve_lu_piv_1_x_with_merge_ooc     (Element e);
  extern bool op_solve_lu_piv_2_x_without_branch_ooc (Element e);
  extern bool op_solve_lu_piv_2_x_with_branch_ooc    (Element e);

  extern bool op_solve_lu_piv_1_r_without_merge_ooc  (Element e);
  extern bool op_solve_lu_piv_1_r_with_merge_ooc     (Element e);
  extern bool op_solve_lu_piv_2_r_without_branch_ooc (Element e);
  extern bool op_solve_lu_piv_2_r_with_branch_ooc    (Element e);

  extern bool op_check_lu_piv_1_ooc                  (Element e);
  extern bool op_check_lu_piv_2_ooc                  (Element e);
  // ---------------------------------------------------
  extern bool op_check_solution                      (Element e);
  extern bool op_improve_solution                    (Element e);
  // ---------------------------------------------------
  // ---------------------------------------------------
  extern bool op_test                                (Element e);
}


#endif
